package com.mender.common.utils;

import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Slf4j
@Data
@AllArgsConstructor
public class MinIOUtils {

    private final MinioClient minioClient;
//   bucketName 桶名称
    private final String bucketName;



    public String uploadFile(MultipartFile file) {

        if (file == null || file.isEmpty()) {
            log.warn("上传失败：文件为空");
            return "文件为空";
        }
        // 获取文件名
        String originalFilename = file.getOriginalFilename();
        // 使用uuid生成新的文件名
        String objectName = UUID.randomUUID().toString() +
                originalFilename.substring(originalFilename.lastIndexOf("."));
        try {
//            判断存储桶是否存在
            boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!found) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }

            try (InputStream inputStream = file.getInputStream()) {
                minioClient.putObject(
                        PutObjectArgs.builder()
                                .bucket(bucketName)
                                .object(objectName)
                                .stream(inputStream, file.getSize(), -1)
                                .contentType(file.getContentType())
                                .build()
                );
            }

            log.info("✅ 文件上传成功：{}", objectName);
            return getPresignedObjectUrl(objectName);
        }catch (Exception e) {
            log.error("文件上传失败", e);
            throw new RuntimeException("文件上传失败，请稍后重试", e);
        }
    }

    /**
     * 获取文件url地址
     * @param objectName 文件名称
     * @return
     * @throws Exception
     */
    public String getPresignedObjectUrl(String objectName)  {
        try {
            String filePath = minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .method(Method.GET)
                            .build()
            );

            // 去掉url中的时间戳
            int idx = filePath.indexOf('?');
            return idx == -1 ? filePath : filePath.substring(0, idx);
        } catch (Exception e) {
            log.error("获取文件 URL 失败，bucket={}, object={}", bucketName, objectName, e);
            throw new RuntimeException("获取文件访问地址失败", e);
        }
    }

    /**
     * 批量删除文件
     * @param filePaths<String> 需要删除的文件列表
     * @return Result
     */
    public Iterable<Result<DeleteError>> removeFiles(List<String> filePaths) {
        List<DeleteObject> objectPaths = filePaths.stream()
                .map(filePath -> new DeleteObject(filePath))
                .collect(Collectors.toList());
        return minioClient.removeObjects(
                RemoveObjectsArgs.builder().bucket(bucketName).objects(objectPaths).build());
    }

}
